package com.dlc.shop.platform.controller.cdek;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.dlc.shop.bean.model.*;
import com.dlc.shop.common.response.ServerResponseEntity;
import com.dlc.shop.common.util.Json;
import com.dlc.shop.delivery.common.param.DeliveryOrderItemParam;
import com.dlc.shop.delivery.common.service.DeliveryOrderItemService;
import com.dlc.shop.delivery.common.service.DeliveryOrderService;
import com.dlc.shop.service.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;

@RestController
@RequestMapping("/platform/cdek")
@Tag(name = "cdek 物流相关接口")
@AllArgsConstructor
public class CdekAuthController {

    private static final Logger logger = LoggerFactory.getLogger(CdekAuthController.class);

    private final CdekAuthTokenService cdekAuthTokenService;
    private final OrderService orderService;
    private final UserAddrOrderService userAddrOrderService;
    private final OrderItemService orderItemService;
    private final SkuService skuService;
    private final DeliveryOrderService deliveryOrderService;
    private final DeliveryOrderItemService deliveryOrderItemService;
    private final AttachFileService attachFileService;
    private final PlatformAddrService platformAddrService;
    /**
     * Интеграция / 对接：API 2.0
     * Номер договора / 合同号：CN-IC-153
     * Логин / 账号（client_id）：G7VHY7NvGTwtjwc9FhtplD0zMkbRc8c4
     * Пароль / 密码（client_secret）：rOQF2vxG0S0RmPzw7V8vZa7Q4SuzIl8o
     */

    @PostMapping("/orders")
    @Operation(summary = "申请下单 " , description = "申请下单")
    public ServerResponseEntity<Map<String,Object>> orders(@RequestBody DeliveryOrderItemParam deliveryOrderParam) {

        //发货订单数据
        List<OrderItem> selectOrderItems = deliveryOrderParam.getSelectOrderItems();
        if (selectOrderItems == null || selectOrderItems.size() == 0) {
            // 未找到所在的订单
            return ServerResponseEntity.showFailMsg("请选择发货商品");
        }

        //用户地址
        UserAddrOrder userAddrOrder = userAddrOrderService.getById(deliveryOrderParam.getAddrOrderId());

        //发货地址
        PlatformAddr platformAddr = platformAddrService.getById(deliveryOrderParam.getOutletConfigId());

        CdekOrdersRequest cdekOrdersRequest = new CdekOrdersRequest();
//        cdekOrdersRequest.setNumber(deliveryOrder.getOrderNumber());
        cdekOrdersRequest.setTariff_code(186);              //中俄快递 库到库
        cdekOrdersRequest.setDate_invoice(new Date());      //发货时的发票日期
        cdekOrdersRequest.setShipper_name("CDEK");     //承运商名称
        cdekOrdersRequest.setShipper_address("Novosibirsk");  //承运商地址

        //收件方
        OrderContact orderContact = new OrderContact();
        //电话号码列表
        List<OrderContactPhone> orderContactPhones = new ArrayList<>();
        OrderContactPhone orderContactPhone = new OrderContactPhone();
        orderContactPhone.setNumber(userAddrOrder.getMobile());
        orderContactPhones.add(orderContactPhone);
        orderContact.setPhones(orderContactPhones);
        orderContact.setName(userAddrOrder.getReceiver());                 //收件方姓名
        cdekOrdersRequest.setRecipient(orderContact);

        //寄件地址
        OrderLocation fromOrderLocation = new OrderLocation();
        fromOrderLocation.setAddress(platformAddr.getProvince()+platformAddr.getCity()+platformAddr.getArea()+platformAddr.getAddr());
        fromOrderLocation.setCountry_code("CN");
        fromOrderLocation.setPostal_code(platformAddr.getPostCode());
        cdekOrdersRequest.setFrom_location(fromOrderLocation);

        //收件地址
        OrderLocation toOrderLocation = new OrderLocation();
        toOrderLocation.setAddress(userAddrOrder.getProvince() + userAddrOrder.getCity() + userAddrOrder.getArea() + userAddrOrder.getAddr());
        //toOrderLocation.setAddress("Челябинская область, Челябинск, тракторозаводский район, улица Волочаевская,дом 13");
        toOrderLocation.setCountry_code("RU");
        toOrderLocation.setPostal_code(userAddrOrder.getPostCode());
        cdekOrdersRequest.setTo_location(toOrderLocation);

        //实际卖家
        OrderSeller orderSeller = new OrderSeller();
        orderSeller.setAddress(fromOrderLocation.getAddress());
        cdekOrdersRequest.setSeller(orderSeller);

        //包装件列表
        List<OrderPackage> orderPackages = new ArrayList<>();
        OrderPackage orderPackage = new OrderPackage();
        List<OrderPackageItem> orderPackageItemList = new ArrayList<>();    //内件列表


        Double weight = 0d;
        for (OrderItem vo : selectOrderItems)
        {
            //计算包裹重量
            Sku sku = skuService.getById(vo.getSkuId());
            //每件商品默认 200g 如果页面为 0 的话
            if (sku.getWeight() <= 0.0){
                weight += 1;
                sku.setWeight(1.0);
            }else{
                weight += sku.getWeight();
            }
            //组装内件列表
            OrderPackageItem orderPackageItem = new OrderPackageItem();
            orderPackageItem.setName(vo.getProdName());
            orderPackageItem.setWare_key(vo.getSkuId().toString());
            //单件的代收货款
            OrderMoney orderMoney = new OrderMoney();
            orderMoney.setValue(0d);
            orderPackageItem.setPayment(orderMoney);
            orderPackageItem.setCost(0d);                       //单件申报价值
            orderPackageItem.setWeight(Math.round((float)(sku.getWeight() * vo.getProdCount() * 1000)));                     //单件重量
            orderPackageItem.setWeight_gross(Math.round((float)(sku.getWeight() * vo.getProdCount() * 1000)));               //单件毛重（单位：克）不能少于 weight
            orderPackageItem.setAmount(vo.getProdCount());
            orderPackageItemList.add(orderPackageItem);
        }
        orderPackage.setNumber("1");                                        //包装件序号
        orderPackage.setWeight(Math.round((float)(weight * 1000)));         //总重量
        orderPackage.setItems(orderPackageItemList);                        //内件列表
        orderPackages.add(orderPackage);
        cdekOrdersRequest.setPackages(orderPackages);                       //包装件列表

        String token = cdekAuthTokenService.authToken();
        HttpRequest request = HttpRequest.post(CdekOrdersParams.getFullUrl() + "/orders")
                .header("Content-type", "application/json")
                .header("Authorization", "Bearer " + token);
        HttpResponse response = request.body(Json.toJsonString(cdekOrdersRequest)).execute();
        logger.info("请求数据："+Json.toJsonString(cdekOrdersRequest));
        JSONObject jsonObject = JSON.parseObject(response.body());
        logger.info(response.body());
        if (jsonObject.get("error") != null){
            logger.info(jsonObject.get("message").toString());
            return ServerResponseEntity.showFailMsg(jsonObject.get("message").toString());
        }else{
            String uuid = jsonObject.getJSONObject("entity").getString("uuid");
            Map<String,Object> map = getOrderById(uuid);
            map.put("uuid",uuid);
            if(map.get("errorCode").toString().equals("1")) {
                return ServerResponseEntity.showFailMsg(map.get("msg").toString());
            }
            return ServerResponseEntity.success(map);
        }
    }

    public Map<String,Object> getOrderById(String cdekUuid) {

        //发货订单数据
//        DeliveryOrder deliveryOrder = deliveryOrderService.getById(orderDeliveryId);
//        if (deliveryOrder == null || deliveryOrder.getCdekUuid() == null) {
//            // 未找到所在的订单
//            throw new YamiShopBindException("yami.order.no.exist");
//        }
        String token = cdekAuthTokenService.authToken();
        HttpRequest request = HttpRequest.get(CdekOrdersParams.getFullUrl() + "/orders/" + cdekUuid)
                .header("Content-type", "application/json")
                .header("Authorization", "Bearer " + token);
        HttpResponse response = request.execute();
        JSONObject jsonObject = JSON.parseObject(response.body());
        logger.info("订单数据:"+response.body());
        JSONArray errors = jsonObject.getJSONArray("requests").getJSONObject(0).getJSONArray("errors");
        Map<String,Object> result = new HashMap<>();
        if(errors!= null && errors.size() > 0){
            result.put("errorCode","1");
            result.put("msg",errors.getJSONObject(0).getString("message"));
            result.put("dvyFlowId","");
            return result;
        } else {
            result.put("errorCode","0");
            result.put("msg","成功");
            result.put("dvyFlowId",jsonObject.getJSONObject("entity").getString("cdek_number"));
            return result;
        }
    }

    @GetMapping("/applyForm/{cdekUuid}")
    @Operation(summary = "申请面单 " , description = "申请面单")
    public ServerResponseEntity<String> applyForm(@PathVariable("cdekUuid") String cdekUuid) {

        String token = cdekAuthTokenService.authToken();
        HttpRequest request = HttpRequest.post(CdekOrdersParams.getFullUrl() + "/print/barcodes")
                .header("Content-type", "application/json")
                .header("Authorization", "Bearer " + token);

        Map<String,Object> map = new HashMap<>();
        List<Map<String,String>> list = new ArrayList<>();
        Map<String,String> orderMap = new HashMap<>();
        orderMap.put("order_uuid",cdekUuid);
        list.add(orderMap);
        map.put("orders",list);
        map.put("copy_count",1);
        map.put("format","A6");
        map.put("lang","RUS");

        HttpResponse response = request.body(Json.toJsonString(map)).execute();
        logger.info(response.body());
        JSONObject jsonObject = JSON.parseObject(response.body());
        JSONArray errors = jsonObject.getJSONArray("requests").getJSONObject(0).getJSONArray("errors");
        if(errors != null && errors.size() > 0){
            return ServerResponseEntity.showFailMsg(errors.getJSONObject(0).getString("message"));
        } else {
            String requestUuid = jsonObject.getJSONObject("entity").getString("uuid");
            return ServerResponseEntity.success(requestUuid);
        }
    }

    @GetMapping("/getForm/{requestUuid}")
    @Operation(summary = "获取面单 " , description = "获取面单")
    public ServerResponseEntity<String> getForm(@PathVariable("requestUuid") String requestUuid) {

        String token = cdekAuthTokenService.authToken();
        HttpRequest request = HttpRequest.get(CdekOrdersParams.getFullUrl() + "/print/barcodes/" + requestUuid)
                .header("Content-type", "application/json")
                .header("Authorization", "Bearer " + token);

        HttpResponse response = request.execute();
        logger.info(response.body());
        JSONObject jsonObject = JSON.parseObject(response.body());
        JSONArray errors = jsonObject.getJSONArray("requests").getJSONObject(0).getJSONArray("errors");
        if(errors != null && errors.size() > 0){
            return ServerResponseEntity.showFailMsg(errors.getJSONObject(0).getString("message"));
        } else {

            String fileURL = jsonObject.getJSONObject("entity").getString("url");
            String fileName = getPDFUrl(fileURL,token);
            return ServerResponseEntity.success(fileName);
        }
    }

    public String getPDFUrl(String fileURL, String token) {

        try {
            URL url = new URL(fileURL);

            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();

            // 设置请求方法，GET是最常用的
            httpURLConnection.setRequestMethod("GET");
            httpURLConnection.setRequestProperty("Authorization", "Bearer " + token);

            int responseCode = httpURLConnection.getResponseCode();

            // 总是检查HTTP响应码
            if (responseCode == HttpURLConnection.HTTP_OK) {

                // 打开输入流以从URL读取数据

                InputStream inputStream = httpURLConnection.getInputStream();

                ByteArrayOutputStream buffer = new ByteArrayOutputStream();

                int nRead;

                byte[] data = new byte[16384]; // 16KB的缓冲区

                while ((nRead = inputStream.read(data, 0, data.length)) != -1) {

                    buffer.write(data, 0, nRead);

                }
                buffer.flush();

                String[] fileNameArr = fileURL.split("/");

                String fileName = attachFileService.uploadFile(buffer.toByteArray(),fileNameArr[fileNameArr.length - 1]);
                // 关闭流
                inputStream.close();
                httpURLConnection.disconnect();
                return fileName;
            } else {
                logger.info("下载失败: HTTP错误码 : " + responseCode);
            }
        } catch (Exception e) {

            e.printStackTrace();
        }
        return "";
    }




}
